package com.own.business.login.controller;

import com.own.aop.login.LoginApiAop;
import com.own.aop.login.LoginIgnore;
import com.own.business.login.core.entity.form.AutoLoginForm;
import com.own.business.login.core.entity.form.LoginForm;
import com.own.business.login.core.service.AutoLoginService;
import com.own.business.login.core.service.LoginService;
import com.own.business.login.core.util.LoginCommonUtil;
import com.own.component.client.base.RequestClientManager;
import com.own.component.common.base.controller.BaseController;
import com.own.component.common.exception.BusinessSimpleException;
import com.own.component.common.model.R;
import com.own.component.common.model.ResultModel;
import com.own.component.common.util.IpUtil;
import com.own.component.log.operation.aop.LogOperationAop;
import com.own.component.store.core.util.base.RsaKeyUtil;
import com.own.constant.ConstantApiPrefix;
import com.own.constant.ConstantBeanSuffix;
import com.own.exception.ExceptionEnum;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * LoginController
 *
 * @author chenxueli
 * @date 2023-06-25 21:47:38
 */
@Slf4j
@Tag(name = "普通登录授权" + ConstantBeanSuffix.CONTROLLER)
@RestController
@RequestMapping(ConstantApiPrefix.BASE_API_V1_PREFIX + "login")
public class LoginController extends BaseController {

    @Resource
    private LoginService loginService;
    @Resource
    private AutoLoginService autoLoginService;

    @Resource
    private RsaKeyUtil rsaKeyUtil;
    @Resource
    private LoginCommonUtil loginCommonUtil;

    @Resource
    private RequestClientManager requestClientManager;
    @Resource
    private HttpServletRequest request;

    @LoginApiAop(account = "#form.account", type = "text")
    @LoginIgnore
    @LogOperationAop
    @Operation(summary = "登录")
    @PostMapping("/")
    public ResultModel<String> login(
            @RequestBody LoginForm form,
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        form.check();
        // 解密加密的密码信息，如果没有key，表示为不加密登录
        if (StringUtils.isNotBlank(form.getKey())) {
            var password = rsaKeyUtil.decrypt(form.getKey(), form.getPassword());
            form.setPassword(password);
        }
        // 设置登录用户的ip地址
        form.setIp(IpUtil.getIpAddress(request));
        // 执行通用登录方法
        var responseVo = loginCommonUtil.login(() -> loginService.loginUser(form), request, response);
        // 返回信息
        return R.success(responseVo.getToken(), "登录成功");
    }

    @LoginApiAop(isCheck = false, account = "", type = "auto")
    @LoginIgnore
    @LogOperationAop
    @Operation(summary = "刷新获取新的token")
    @PostMapping("/auto")
    public ResultModel<String> refreshToken(
            @RequestBody AutoLoginForm form,
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        if (StringUtils.isBlank(form.getKey()) || StringUtils.isBlank(form.getPassword())) {
            throw new BusinessSimpleException(ExceptionEnum.Default.AUTO_LOGIN_NOT_FOUND);
        }
        // 解密加密的密码信息
        var password = rsaKeyUtil.decrypt(form.getKey(), form.getPassword());
        // 登录
        var responseVo = autoLoginService.login(password, request, response);
        // 返回信息
        return R.success(responseVo.getToken(), "登录成功");
    }

    @LogOperationAop
    @Operation(summary = "获取自动登录的key")
    @PostMapping("/auto/key")
    public ResultModel<String> autoLogin() {
        var client = requestClientManager.client(request);
        var key = autoLoginService.createAutoLoginKey(client);
        return R.success(key, "获取成功");
    }

}
